﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Sinacor.Infra.Core.Licensing;
using System.IO;
using Sinacor.Infra.Common;
using Sinacor.Infra.Service.Security.Authorization;

namespace Sinacor.Infra.Service.Security.Authorization
{
    /// <summary>
    /// Classe responsavel por controlar a validação de licença
    /// </summary>
    public class LicensingManager : CrossAppDomainSingleton<LicensingManager>
    {
        #region Fields

        private LicensingValidator _licensingValidator;
        private SignedLicensing _signedLicensing;
        private byte[] licensingByteArray;

        #endregion

        #region Constructors

        public LicensingManager()
        {

        }
        #endregion

        #region Public Members

        /// <summary>
        /// Array binario que compoem o arquivo de licença
        /// </summary>
        public byte[] EncryptedLicensing
        {
            get { return licensingByteArray; }
            set
            {
                try
                {
                    licensingByteArray = value;

                    //Cria o objeto de Licensing Assinado
                    _signedLicensing = new SignedLicensing();

                    try
                    {
                        //Lê o arquivo de licenciamento carregando os dados para o objeto.
                        _signedLicensing.LoadLicensingFromByteArray(licensingByteArray);

                        //Cria o objeto de validação a partir da licença assinada que foi criada
                        _licensingValidator = new LicensingValidator(_signedLicensing);
                    }
                    catch (LicensingCorruptedException lcex)
                    {
                        //SystemErrorLog.Log(lcex);

                        throw new Exception("Corrupted Licensing Data.", lcex);
                    }
                    catch (LicensingExpiredException leex)
                    {
                        //SystemErrorLog.Log(leex);

                        throw new Exception("Expired Licensing.", leex);
                    }
                }
                catch (Exception ex)
                {
                    //SystemErrorLog.Log(ex);

                    throw new Exception("Loading Licensing Fail.", ex);
                }
            }
        }

        /// <summary>
        /// Lista de módulos de compõem a licença
        /// </summary>
        public List<Module> Modules
        {
            get
            {
                List<Module> modules = null;

                if (_licensingValidator != null)
                    modules = _licensingValidator.SignedLicensing.Licensing.Modules;

                return modules;
            }
        }

        /// <summary>
        /// Valida se a empresa possui um licença ativa
        /// </summary>
        /// <param name="companyName">Dados da empresa</param>
        /// <returns></returns>
        public bool ValidateCompany(Company company)
        {
            bool result = false;

            if (_licensingValidator != null)
                result = _licensingValidator.Validate(new Core.Licensing.Company(company.Name, company.CGC, company.Id));

            return result;
        }

        /// <summary>
        /// Valida se o módulo requisitado possui uma licença ativa
        /// </summary>
        /// <param name="companyName">Dados da empresa</param>
        /// <returns></returns>
        public bool ValidateModule(Company company, string moduleID, bool plus)
        {
            bool result = false;

            if (_licensingValidator != null)
            {
                Core.Licensing.Company companyCore = new Core.Licensing.Company(company.Name, company.CGC, company.Id);
                result = _licensingValidator.Validate(companyCore, new Module() { Monogram = moduleID, Plus = plus });
            }

            return result;
        }

        /// <summary>
        /// Valida se a licença possui o módulo Kernel+
        /// </summary>
        /// <param name="companyName">Dados da empresa</param>
        /// <returns></returns>
        public bool ValidateKernelPlus(Company company)
        {
            bool result = false;

            if (_licensingValidator != null)
            {
                Core.Licensing.Company companyCore = new Core.Licensing.Company(company.Name, company.CGC, company.Id);
                result = _licensingValidator.Validate(companyCore, new Module("Kernel+", "KNL", true));
            }

            return result;
        }

        #endregion
    }
}
